package com.ofcoder.tool.validator.service;

import com.ofcoder.tool.validator.exception.StrategyNotFoundException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: yuanyuan.liu
 * @date: 2019/1/21 15:16
 */
@Component
public class ValidatorFactory {
    private static final Logger logger = LoggerFactory.getLogger(ValidatorFactory.class);
    private static final Map<String, IParamStrategy> STRATEGY_MAP = new HashMap<>();
    private static final Map<String, IVerifyHandler> VERIFY_HANDLER_MAP = new HashMap<>();
    @Autowired(required = false)
    private List<IParamStrategy> strategies;
    @Autowired(required = false)
    private List<IVerifyHandler> verifyHandlers;

    @PostConstruct
    public void init() {
        initStrategy();
        initVerifyHandler();
    }

    private void initVerifyHandler() {
        if (CollectionUtils.isEmpty(verifyHandlers)) {
            logger.warn("call ParamStrategyFactory.initVerifyHandler, verifyHandlers is empty.");
            return;
        }
        for (IVerifyHandler han : verifyHandlers) {
            VERIFY_HANDLER_MAP.put(han.primaryKey(), han);
        }
    }

    private void initStrategy() {
        if (CollectionUtils.isEmpty(strategies)) {
            logger.warn("call ParamStrategyFactory.initStrategy, strategies is empty.");
            return;
        }
        for (IParamStrategy strategy : strategies) {
            STRATEGY_MAP.put(strategy.primaryKey(), strategy);
        }
    }

    public IParamStrategy getStrategy(String primaryKey) {
        if (MapUtils.isEmpty(STRATEGY_MAP)) {
            throw new StrategyNotFoundException("call ParamStrategyFactory.getStrategy, STRATEGY_MAP is empty......");
        }
        IParamStrategy strategy = STRATEGY_MAP.get(primaryKey);
        if (strategy == null) {
            throw new StrategyNotFoundException(String.format("call ParamStrategyFactory.getStrategy, primaryKey:[%s], without this strategy.", primaryKey));
        }
        return strategy;
    }

    public IVerifyHandler getVerifyHandler(String primaryKey) {
        if (MapUtils.isEmpty(VERIFY_HANDLER_MAP)) {
            throw new StrategyNotFoundException("call ParamStrategyFactory.getVerifyHandler, VERIFY_HANDLER_MAP is empty......");
        }
        IVerifyHandler handler = VERIFY_HANDLER_MAP.get(primaryKey);
        if (handler == null) {
            throw new StrategyNotFoundException(String.format("call ParamStrategyFactory.getVerifyHandler, primaryKey:[%s], without this VerifyHandler.", primaryKey));
        }
        return handler;
    }

}
